package fr.toto.triseries;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.regex.Pattern;

import com.kokotchy.betaSeriesAPI.model.Episode;
import com.kokotchy.betaSeriesAPI.model.Show;
import com.kokotchy.betaSeriesAPI.model.Subtitle;
import com.kokotchy.betaSeriesAPI.model.SubtitleLanguage;

import fr.toto.constantes.Constantes;

public class Regex implements Constantes {

	public static String VIDEOFILE = settings.getExtsRegex();

	public static final String SUBTITLEFILE = "\\.(srt|ass|SRT|ASS)$";

	public static final String SERIE = "(?!sample|SAMPLE)(.*)(?: - |\\.| |-|\\[)[sS]?(\\d{1,2})[XxEe-](\\d{2,3})(?: - |\\.| |\\])(.*)";

	public static final String SAISONEPISODE = "( - )?(([Ss]\\d{1,2}[eE]\\d{2,3})|(\\d{1,2}[xX]\\d{2,3}))( - )?";

	public static final String BADCHARS = "[\\\"<>\\\\/;\\:\\?\\|\\*\\{\\}\\]\\[]";

	public static final String SHOWNAME = "[-\\(]?((20|19)\\d{2}|UK|US)\\)?";

	private static String format = settings.getFormatFile();
	private static String destdir = settings.getDestDir().toString();

	public static Pattern EnglishPattern = Pattern
			.compile("(\\.|-| )(VO|EN|vo|en|En|English|english)(\\.|-| )");
	public static Pattern FrenchPattern = Pattern
			.compile("(\\.|-| )(VF|FR|vf|fr|Fr|French|french|français)(\\.|-| )");

	private static String getEpisode(Episode ep) {
		String path = format.replace("{SERIE}",
				ep.getShow().replaceAll(BADCHARS, ""));
		path = path.replace("{NB}", ep.getNb());
		path = path.replace("{SAISON:1}", String.format("%d", ep.getSeason()));
		path = path
				.replace("{SAISON:2}", String.format("%02d", ep.getSeason()));
		path = path
				.replace("{EPISODE:1}", String.format("%d", ep.getEpisode()));
		path = path.replace("{EPISODE:2}",
				String.format("%02d", ep.getEpisode()));
		path = path
				.replace("{GLOBAL:1}", String.format("%01d", ep.getGlobal()));
		path = path
				.replace("{GLOBAL:2}", String.format("%02d", ep.getGlobal()));
		path = path
				.replace("{GLOBAL:3}", String.format("%03d", ep.getGlobal()));
		path = path.replace("{TITRE}", ep.getTitle().replaceAll(BADCHARS, ""));
		return path;
	}

	public static Path getEpisodeDest(Episode ep) {
		return Paths.get(destdir, getEpisode(ep));
	}

	public static Path getEpisodeFile(Episode ep) {
		return Paths.get(getEpisode(ep));
	}

	public static Show getBestUrl(Set<Show> shows, String titre) {
		return getBestUrl(shows, titre, -1);
	}

	public static Show getBestUrl(Set<Show> shows, String titre, int threshold) {
		Show res = null;
		for (Show s : shows) {
			if (s.getUrl().equalsIgnoreCase(titre.replaceAll("\\W", "")))
				return s;
			if (s.getTitle().equalsIgnoreCase(titre))
				return s;
			int i = approcheString(titre, s.getTitle());
			if (s.getTitle().replaceAll(Regex.SHOWNAME, " ").trim()
					.equalsIgnoreCase(titre))
				i = i + 10;
			if (titre.replaceAll(Regex.SHOWNAME, " ").trim()
					.equalsIgnoreCase(s.getTitle()))
				i = i + 10;
			if (i > threshold) {
				threshold = i;
				res = s;
			}
		}
		return res;
	}

	public static Subtitle getBestSubtitle(Set<Subtitle> subs, String args,
			SubtitleLanguage lang, int ep, int se) {
		int best = -100;
		Subtitle sub = null, res;
		String item = "";
		Pattern p;
		SubtitleLanguage wronglang;
		if (lang.equals(SubtitleLanguage.VF)) {
			wronglang = SubtitleLanguage.VO;
			p = Pattern.compile("(\\.|-| )(VO|EN|vo|en|En)(\\.|-| )");
		} else {
			wronglang = SubtitleLanguage.VF;
			p = Pattern.compile("(\\.|-| )(VF|FR|vf|fr|Fr)(\\.|-| )");
		}
		for (Subtitle s : subs) {
			if (s.getLanguage().equals(wronglang))
				continue;
			if (s.getContent().size() == 0) {
				if (!s.getFile().matches(
						String.format("(.*)%d(.*)%02d(.*)", se, ep)))
					continue;
				if (!s.getFile().matches(
						"(.*)(" + settings.getSubRegexWith() + ")(.*)"))
					continue;
				if (s.getFile().matches(
						"(.*)(" + settings.getSubRegexWithout() + ")(.*)"))
					continue;
				int i = approcheString(s.getFile(), args);
				if (i > best) {
					best = i;
					item = null;
					sub = s;
				}
				if (settings.isDebug())
					System.out.print(String.format(
							DEBUGMSG.getString("possibleSub"), s.getFile(), i));
			} else {
				for (String it : s.getContent()) {
					if (s.getLanguage().equals(SubtitleLanguage.VOVF)
							&& p.matcher(it).find())
						continue;
					if (!it.matches(String.format("(.*)%d(.*)%02d(.*)", se, ep)))
						continue;
					if (!it.matches("(.*)(" + settings.getSubRegexWith() + ")(.*)"))
						continue;
					if (it.matches("(.*)(" + settings.getSubRegexWithout() + ")(.*)"))
						continue;
					int i = approcheString(it, args);
					if (i > best) {
						best = i;
						item = it;
						sub = s;

					}
					if (settings.isDebug())
						System.out.print(String.format(
								DEBUGMSG.getString("possibleSub"), s.getFile(),
								i));
				}
			}
		}
		if (sub == null)
			return null;
		if (sub.getContent().size() == 1)
			return sub;
		res = new Subtitle();
		res.setFile(sub.getFile());
		res.setUrl(sub.getUrl());
		res.addItem(item);
		return res;
	}

	private static int approcheString(String s1, String s2) {
		int res = 0;
		s1 = s1.toLowerCase();
		s2 = s2.toLowerCase();
		String[] t1 = s1.split("\\W");
		for (String s : t1) {
			if (!s.isEmpty())
				if (s2.contains(s))
					res++;
				else
					res--;
		}
		String[] t2 = s2.split("\\W");
		for (String s : t2) {
			if (!s.isEmpty())
				if (s1.contains(s))
					res++;
				else
					res--;
		}
		return res;
	}

	public static String printEpisode(Episode ep, String printFormat) {

		String EpisodePrint = printFormat.replace("{SERIE}", ep.getShow());
		EpisodePrint = EpisodePrint.replace("{NB}", ep.getNb());
		EpisodePrint = EpisodePrint.replace("{SAISON:1}",
				String.format("%d", ep.getSeason()));
		EpisodePrint = EpisodePrint.replace("{SAISON:2}",
				String.format("%02d", ep.getSeason()));
		EpisodePrint = EpisodePrint.replace("{EPISODE:1}",
				String.format("%d", ep.getEpisode()));
		EpisodePrint = EpisodePrint.replace("{EPISODE:2}",
				String.format("%02d", ep.getEpisode()));
		EpisodePrint = EpisodePrint.replace("{GLOBAL:1}",
				String.format("%01d", ep.getGlobal()));
		EpisodePrint = EpisodePrint.replace("{GLOBAL:2}",
				String.format("%02d", ep.getGlobal()));
		EpisodePrint = EpisodePrint.replace("{GLOBAL:3}",
				String.format("%03d", ep.getGlobal()));
		EpisodePrint = EpisodePrint.replace("{TITRE}", ep.getTitle()
				.replaceAll(BADCHARS, ""));
		return EpisodePrint;
	}

}
